/*
 * Copyright 2013-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.example.utils.AppUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author 游家纨绔
 * @dateTime 2023-09-09 10:00
 * @apiNote TODO 支付宝异步通知控制器
 */
@Controller
public class SyncNotifyController {

	// 接受支付宝返回的异步通知信息（这里是用户输入支付密码，确认支付后面向商户的回调接口）
	@RequestMapping("/getNotify")
	public void getNotify(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
		// 获取支付宝返回的信息
		Map<String, String> params = new HashMap<>();
		Map<String, String[]> parameterMap = request.getParameterMap();
		for (String name : parameterMap.keySet()) {
			String[] value = parameterMap.get(name);
			String valueStr = "";
			for (int i = 0; i < value.length; i++) {
				valueStr = (i == value.length - 1) ? valueStr + value[i] : valueStr + value[i] + " ,";
			}
			params.put(name, valueStr);
		}

		// 调用支付宝的SDK验证公钥，字符编码，签名方式
		boolean signVerified = AlipaySignature.rsaCheckV1(params, AppUtils.alipay_public_key,
		                                                  AppUtils.charset, AppUtils.sign_type);

		/** 一般建议商户验签：保证数据在传输过程中没有篡改
		 *  1、需要验证通知数据中的 out_trade_no 和我们创建的订单号是否一致
		 *  2、判断 total_amount 的金额和我们实际发送的金额是否一致
		 *  3、验证 seller_id 是否对应商户
		 *  4、验证 app_id 是否为商户本身
		 *  (这里是我们的第一个简易demo，并没有进行自定义验证订单号、金额、订单状态、商户等)
		 */
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		// 验签成功
		if (signVerified) {
			// 获取商户订单号
			String outTradeNo = request.getParameter("out_trade_no");
			// 支付宝的交易号
			String tradeNo = request.getParameter("trade_no");
			// 获取交易状态
			String tradeStatus = request.getParameter("trade_status");
			if (tradeStatus.equals("TRADE_SUCCESS")) {
				System.out.println("商户订单号: " + outTradeNo + ", 支付宝的交易号: " + tradeNo + ", 交易成功");
				out.println("success");
			} else {
				System.out.println("商户订单号: " + outTradeNo + ", 支付宝的交易号: " + tradeNo + ", 交易失败");
				out.println("fail");
			}
		}
	}

}
